package py.com.alfa.escriba.gui.controller;

import java.io.Serializable;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.WebApplicationContext;
import org.thymeleaf.TemplateEngine;
import org.winter.dialect.response.JsonResponse;
import org.winter.utils.command.AjaxResponse;
import org.winter.utils.command.ControllerObject;

import py.com.alfa.escriba.gui.controller.object.PickListFuncObject;
import py.com.alfa.escriba.gui.controller.object.admin.PerfilesControllerObject;
import py.com.alfa.escriba.gui.controller.view.View;
import py.com.alfa.escriba.gui.controller.view.ViewManager;
import py.com.alfa.escriba.gui.dto.admin.PerfilDTO;
import py.com.alfa.escriba.gui.dto.admin.PerfilDatosDTO;
import py.com.alfa.escriba.gui.rest.services.AdministracionService;
import py.com.alfa.escriba.gui.services.HelperService;
import py.com.alfa.escriba.gui.session.SystemInfo;
import py.com.alfa.escriba.gui.spring.processors.SpringBean;
import py.com.sif.rest.client.spring.exception.RestClientException;

@Controller
@Scope("session")
@SessionAttributes("perfiles")
@RequestMapping("/perfiles")
public class PerfilesController implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3807025844096914070L;
	private final static String PAGE_NAME = "pag:perfiles";
	private final static String CONTROLLER_OBJECT_NAME = "perfiles";
	
	private Logger log = LoggerFactory.getLogger(getClass());
	@SpringBean private SystemInfo systemInfo;
	@SpringBean private ViewManager viewManager;
	@SpringBean private AdministracionService administracionService;
	@SpringBean private HelperService helperService;
	
	@Autowired
	private WebApplicationContext wac;
	
	@Autowired
	private TemplateEngine templateEngine;
	@ControllerObject	
	private PerfilesControllerObject perfiles;
	private Locale locale;
	
	
	public PerfilesController() {
		this.loadObjects();
	}

	private void loadObjects() {
		setLocale(LocaleContextHolder.getLocale());
	}

	private String verifAuto() {
		Subject subject = SecurityUtils.getSubject();
		if (subject == null || !subject.isAuthenticated()) {
			return "redirect:/";
		}		
		Boolean permitted = subject.isPermitted(PerfilesController.PAGE_NAME);
		systemInfo.setSystemError(false);
		if (!permitted) {
			systemInfo.setSystemError(true);
			systemInfo.setErrorMessage("El usuario no esta autorizado para utilizar este recurso");
			return "error";
		}
		return null;
	}

	
	@ModelAttribute(CONTROLLER_OBJECT_NAME)
	public PerfilesControllerObject getPerfiles() {
		return this.perfiles;
	}

	public void setPerfiles(PerfilesControllerObject listas) {
		this.perfiles = listas;
	}

	public Locale getLocale() {
		return locale;
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
	}
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String homePage(Model model, HttpServletRequest request, HttpServletResponse response) {
		this.log.info("perfiles!");
		try {
			this.getPerfiles().view().disableAll();
			String auto = this.verifAuto();
			if ( auto != null ) {
				return auto;
			}
			this.getPerfiles().setPerfiles(this.administracionService.listPerfil());
			this.getPerfiles().setFuncionalidades(this.administracionService.listFuncionalidad());
			this.getPerfiles().view().enable().lista();
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
		}
		return View.PERFILES;
	}

	@RequestMapping(value = "/agregarPerfil", method = RequestMethod.POST)
	public @ResponseBody JsonResponse agregarPerfil(Model model, HttpServletRequest request, HttpServletResponse response, 
		@AjaxResponse(View.PERFILES) JsonResponse jResponse) {
		this.log.info("perfiles - Nuevo!");
		this.getPerfiles().setPerfil(new PerfilDTO());
		this.getPerfiles().getPerfil().setPickListFunc(new PickListFuncObject(this.getPerfiles().getFuncionalidades()));
		this.getPerfiles().view().disableAll().enable().perfil();

		return jResponse.success(request, response, wac, model, templateEngine);
	}	

	
	@RequestMapping(value = "/cancelar/{operacion}", method = RequestMethod.POST)
	public @ResponseBody JsonResponse cancelar(Model model, HttpServletRequest request, HttpServletResponse response, 
		@AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult, 
		@PathVariable("operacion") String operacion) {
		this.log.info("perfiles - cancelar! {}", operacion);
		try {
			if ( operacion == null ) {
				return jResponse.error("Debe informar la operacion a cancelar");
			}
			if ( "PERFILES".equals(operacion)) {
				this.getPerfiles().setPerfiles(this.administracionService.listPerfil());
			    this.getPerfiles().setPerfil(null);
			    this.getPerfiles().view().disableAll().enable().lista();
			    jResponse.setView(View.PERFILES);
			}			
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
			if (e.getCause() != null && e.getCause() instanceof RestClientException) {
				return jResponse.error(e.getCause().getMessage());
			}
		}
		return jResponse.success(request, response, wac, model, templateEngine);
	}	
	
	@RequestMapping(value = "/guardarPerfil", method = RequestMethod.POST)
	public @ResponseBody JsonResponse guardarPerfil(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult) {
		this.log.info("\n==============\nGUARDANDO PERFIL! \n==============\n");
		try {
			PerfilDTO obj = this.getPerfiles().getPerfil();
			this.log.info("Perfil: {}", obj);
			
			if ( obj.getId() == null ) {
				obj.setFuncAsignadas(this.getPerfiles().getPerfil().getPickListFunc().getPickTarget());
			   this.administracionService.createPerfil(obj);
			} else {
				obj.setAgregar(new PerfilDatosDTO());
				obj.getAgregar().setFuncionalidades(this.getPerfiles().getPerfil().getPickListFunc().getPickTarget());
				obj.setEliminar(new PerfilDatosDTO());
				obj.getEliminar().setFuncionalidades(this.getPerfiles().getPerfil().getPickListFunc().getPickSource());
			   this.administracionService.savePerfil(obj);
			}
			
			this.getPerfiles().setPerfiles(this.administracionService.listPerfil());
			this.getPerfiles().view().disableAll().enable().lista();
			jResponse.setView(View.PERFILES);
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
			if (e.getCause() != null && e.getCause() instanceof RestClientException) {
				return jResponse.error(e.getCause().getMessage());
			}
		}
		
		return jResponse.success(request, response, wac, model, templateEngine);
	}	
	
	@RequestMapping(value = "/editarPerfil/{index}", method = RequestMethod.POST)
	public @ResponseBody JsonResponse editarPerfil(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFILES) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult, 
		         @PathVariable("index") String ind) {
		this.log.info("\n============== EDITAR PERFIL! {}\n==============\n", ind);
		try {
			Integer index = Integer.parseInt(ind);
			PerfilDTO obj = this.getPerfiles().getPerfiles().get(index);
			this.log.info("PERFIL: {}", obj);
			PerfilDTO perfil = this.administracionService.showPerfil(obj.getId());
			this.getPerfiles().setPerfil(perfil);
			this.getPerfiles().getPerfil().setPickListFunc(new PickListFuncObject(perfil.getFuncNoAsignadas()));
			this.getPerfiles().getPerfil().getPickListFunc().setPickTarget(perfil.getFuncAsignadas());
			
			this.getPerfiles().view().disableAll().enable().perfil();
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
			if (e.getCause() != null && e.getCause() instanceof RestClientException) {
				return jResponse.error(e.getCause().getMessage());
			}
		}
		return jResponse.success(request, response, wac, model, templateEngine);
	}

	@RequestMapping(value = "/eliminarPerfil/{index}", method = RequestMethod.POST)
	public @ResponseBody JsonResponse eliminarPerfil(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFILES) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult, 
		         @PathVariable("index") String ind) {
		this.log.info("\n============== BORRAR PERFIL! {}\n==============\n", ind);
		try {
			Integer index = Integer.parseInt(ind);
			PerfilDTO obj = this.getPerfiles().getPerfiles().get(index);
			this.log.info("PERFIL: {}", obj);
			this.administracionService.deletePerfil(obj.getId());
			this.getPerfiles().setPerfiles(this.administracionService.listPerfil());
			this.getPerfiles().view().disableAll().enable().lista();
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
			if (e.getCause() != null && e.getCause() instanceof RestClientException) {
				return jResponse.error(e.getCause().getMessage());
			}
		}
		return jResponse.success(request, response, wac, model, templateEngine);
	}
	
	@RequestMapping(value = "/addToPickList", method = RequestMethod.POST)
	  public @ResponseBody JsonResponse addToPickList(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult) {
	    log.info("\n==============\nAdd to Pick List!\n==============\n");
	    this.getPerfiles().getPerfil().getPickListFunc().add();
	    jResponse =  jResponse.success(request, response, wac, model, templateEngine);
	    return jResponse;
	  }
	  
	  @RequestMapping(value = "/addAllToPickList", method = RequestMethod.POST)
	  public @ResponseBody JsonResponse addAllToPickList(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult) {
	    log.info("\n==============\nAdd all to Pick List!\n==============\n");
	    this.getPerfiles().getPerfil().getPickListFunc().addAll();
	    jResponse =  jResponse.success(request, response, wac, model, templateEngine);
	    return jResponse;
	  }
	  
	  @RequestMapping(value = "/removeFromPickList", method = RequestMethod.POST)
	  public @ResponseBody JsonResponse removeFromPickList(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult) {
	    log.info("\n==============\nRemove from Pick List!\n==============\n");
	    this.getPerfiles().getPerfil().getPickListFunc().remove();
	    jResponse =  jResponse.success(request, response, wac, model, templateEngine);
	    return jResponse;
	  }
	  
	  @RequestMapping(value = "/removeAllFromPickList", method = RequestMethod.POST)
	  public @ResponseBody JsonResponse removeAllFromPickList(Model model,HttpServletRequest request, HttpServletResponse response, 
		         @AjaxResponse(View.PERFIL) JsonResponse jResponse, @ModelAttribute(CONTROLLER_OBJECT_NAME) PerfilesControllerObject perfiles, BindingResult bindingResult) {
	    log.info("\n==============\nRemove all from Pick List!\n==============\n");
	    this.getPerfiles().getPerfil().getPickListFunc().removeAll();
	    jResponse =  jResponse.success(request, response, wac, model, templateEngine);
	    return jResponse;
	  }
	
}	

